package com.sbl.controller;

import com.sbl.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

import java.util.Date;
import java.util.Map;

/**
 *  常用的注解控制器
 */

//控制器类
//扫描到该注解之后，生成对象，交给Spring容器管理
@Controller
@RequestMapping(path="/anno")//也可以放在方法上，下面所有的方法的访问都要加上这个路径,用于模块化
@SessionAttributes(value={"username"})   // 把username=小龙再存入到session域中
public class AnnoController {


    /**
     *
     * 1.请求必须携带的参数(键)及值必须   全匹配  (不用RequestParams注解的时候)
     *   将上传 name字段 赋值给username
     * 2. 假如不想做任何返回，可以直接@ResponseBody ，返回void 就ok
     * @RequestParams注解的主要三个方面：
     *    1.给变量取别名（前端的username变成name，本例中username将接收前端name字段）
     *    2.设置变量是否必填
     *    3. 给变量设置默认值
     */
    @RequestMapping(value="/testRequestParam")
    public String testRequestParam(@RequestParam(name = "name",required = true,defaultValue = "龙哥")  String username){
        System.out.println("请求的参数  "+username);
        return "success";
    }


    /**
     *  获取请求体 ，必须是Post请求
     *    以 key-value 键值对的形式(如果需要对象的转化，需要加入jackson依赖)
     *
     */
    @RequestMapping(value="/testRequestBody")
    public String testRequestBody(@RequestBody String body){
        System.out.println("请求体的内容是：  "+body);
        return "success";
    }


    /**
     *  路径占位符  PathVariable
     *  (value="/testPathVariable/{uId}") 和 @PathVariable(name = "uId")  名字uId是一样的
     *          将uId赋值废id
     *
     */
    @RequestMapping(value="/testPathVariable/{uId}")
    public String testPathVariable(@PathVariable(name = "uId") String id){
        System.out.println("占位符的内容是："+id);
        return "success";
    }

    /**
     *  路径占位符  PathVariable
     *  (value="/testPathVariable/{uId}") 和 @PathVariable(name = "uId")  名字uId是一样的
     *          将uId赋值废id
     *
     */
    @RequestMapping(value="/testRequestHeader")
    public String testRequestHeader(@RequestHeader(name = "Accept") String acceptHeader){
        System.out.println("获取请求头的信息："+acceptHeader);
        return "success";
    }

    /**
     *   获取请求指定名称的  cookie 的值
     */
    @RequestMapping(value="/testCookieValue")
    public String testCookieValue(@CookieValue(name = "JSESSIONID") String cookie){
        System.out.println("获取请求名称为JSESSIONID的Cookie的值"+cookie);
        return "success";
    }


    /**
     *
     * ModelAttribute注解 ;测试 方法有返回值，直接通过参数获取了
     *      可以作用在方法上，也可以作用在参数上
     *          如果作用在方法上：表示在控制器的方法之前先执行
     *          如果作用在参数上：获取指定的数据给参数赋值
     */
    @RequestMapping(value="/testModelAttribute1")
    public String testModelAttribute1( User user){
        System.out.println("testModelAttribute1执行了...");
        System.out.println(user);
        return "success";
    }
    //ModelAttribute 情景1
    //该方法会先执行| 作用在方法上表示当前方法会在控制器方法之前执行
    //                所有的控制器都会走这个方法
    @ModelAttribute
    public User showUser(String uname,Integer age){
        System.out.println("有返回值的showUser执行了...");
        // 通过用户查询数据库（模拟）
        User user1 = new User();
        user1.setUname(uname);
//        user1.setAge(age);
        user1.setDate(new Date());
        return user1;
    }
    /**
     *
     * ModelAttribute注解
     * @return
     */
    //情景二 ，获取指定的数据给参数赋值
    @RequestMapping(value="/testModelAttribute2")
    public String testModelAttribute2( @ModelAttribute("abc") User user){
        System.out.println("testModelAttribute2执行了...");
        System.out.println(user);
        return "success";
    }
    //修饰的方法没有返回值；@ModelAttribute作用在参数上，通过参数获取
    // 参数就是 前端对应的
    @ModelAttribute
    public void showUser(String uname,Integer age, Map<String,User> map){
        System.out.println("没有返回值的showUser执行了...");
        // 通过用户查询数据库（模拟）
        User user = new User();
        user.setUname(uname);
        user.setAge(age);
        user.setDate(new Date());
        //将数据存储在Map集合中，在控制器方法中再获取出来
        map.put("abc",user);
    }




    /**
     * SessionAttributes的注解
     *      只能作用在类上
     * 利用Model来存储-> 用于本控制器的多个方法之间参数共享
     */
    @RequestMapping(value="/testSessionAttributes")
    public String testSessionAttributes(Model model){
        System.out.println("testSessionAttributes...");
        // 底层会存储到request域对象中
        model.addAttribute("username","小龙");
        return "success";
    }

    /**
     * 获取值
     * @param modelMap
     * @return
     */
    @RequestMapping(value="/getSessionAttributes")
    public String getSessionAttributes(ModelMap modelMap){
        System.out.println("getSessionAttributes...");
        String msg = (String) modelMap.get("username");
        System.out.println(msg);
        return "success";
    }

    /**
     * 清除  sessionScope（requestScope中也没了..）
     * @param status
     */
    @RequestMapping(value="/delSessionAttributes")
    public String delSessionAttributes(SessionStatus status){
        System.out.println("delSessionAttributes...");
        status.setComplete();
        return "success";
    }




}
